package com.wf.apicommons.utils;

import cn.hutool.core.date.DateUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.GeneratePresignedUrlRequest;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.wf.apicommons.config.COSConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.URL;
import java.util.Date;


/**
 * @Description: 对cos文件操作的工具类
 */
@Slf4j
public class COSFileUtil {

    /**
     * 文件上传
     * @param file 上传的文件
     * @param remarks 文件备注
     * @return 文件访问地址
     */
    public static String fileUpload(MultipartFile file,String remarks) {
        //获取cos客户端
        COSClient cosClient =getCOSClient();;
        try{
            //文件名称
            String filename = SnowflakeUtil.getID().concat("_").concat(file.getOriginalFilename());
            //目录的生成 当前日期
            String date = DateUtil.format(new Date(), "yyyy-MM-dd");
            //此处目录规则为  当前日期/文件名称
            String key = remarks.concat("/").concat(date).concat("/").concat(filename);
            PutObjectRequest putObjectRequest = new PutObjectRequest(COSConfig.BUCKET_NAME, key, multipartFileToFile(file));
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            log.info("putObjectResult:"+putObjectResult);
            //删除本地上传资源
            deleteTempFile(multipartFileToFile(file));
            Date expiration = new Date(new Date().getTime() + 5 * 60 * 10000);
            GeneratePresignedUrlRequest req =new GeneratePresignedUrlRequest(COSConfig.BUCKET_NAME, key, HttpMethodName.GET);
            // 设置签名过期时间(可选), 若未进行设置, 则默认使用 ClientConfig 中的签名过期时间(1小时)
            // 可以设置任意一个未来的时间，推荐是设置 10 分钟到 3 天的过期时间
            req.setExpiration(expiration);
            URL url = cosClient.generatePresignedUrl(req);
            //拼接文件地址
            StringBuffer stringBuffer = new StringBuffer()
                    .append(url.getProtocol())
                    .append("://")
                    .append(url.getHost())
                    .append(url.getPath());

            return stringBuffer.toString();
        }catch (Exception e){
            log.info(e.getMessage());
        }finally {
            //关闭客户端
            closeCOSClient(cosClient);
        }
      return null;
    }

    /**
     * 此方法将multipartFile转为file
     *
     * @param file
     * @return java.io.File
     **/
    private static File multipartFileToFile(MultipartFile file)  {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {

            try {
                InputStream ins = null;
                ins = file.getInputStream();
                toFile = new File(file.getOriginalFilename());
                inputStreamToFile(ins, toFile);
                ins.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return toFile;
    }

    /**
     * 获取流文件
     * @param ins
     * @param file
     */
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 删除本地临时文件
     * @param file
     */
    private static void deleteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }


    /**
     * 删除COS文件
     * @param url 需要删除的文件访问地址
     */
    public static  void deleteCOSFile(String url){
        COSClient cosClient =getCOSClient();
        log.info("即将删除的文件位置:"+url);
    // 指定被删除的文件在 COS 上的路径，即对象键。例如对象键为folder/picture.jpg，则表示删除位于 folder 路径下的文件 picture.jpg
        cosClient.deleteObject(COSConfig.BUCKET_NAME, url);
        //关闭客户端
        closeCOSClient(cosClient);
    }


    /**
     * 获取cos客户端
     * @return
     */
    private static COSClient getCOSClient(){
        COSCredentials cred = new BasicCOSCredentials(COSConfig.SECRET_ID, COSConfig.SECRET_KEY);
        // 2 设置 bucket 的地域
        Region region = new Region("ap-chengdu");
        ClientConfig clientConfig = new ClientConfig(region);
        // 设置使用 https 协议
        clientConfig.setHttpProtocol(HttpProtocol.https);
        //  生成 cos 客户端。
       return new COSClient(cred, clientConfig);
    }

    /**
     * 关闭cos客户端
     * @param cosClient
     */
    private static void closeCOSClient(COSClient cosClient){
        //关闭客户端
        cosClient.shutdown();
    }
}
